//
// Created by dave on 18-7-29.
//
#include <glog/logging.h>
#include "channel.h"
#include "jtt808_handler.h"
#include "../db/location.h"
#include "../codec/data_pack.h"
#include "../codec/data_utils.h"
#include "../codec/platform/plat_common_resp.h"
#include "../codec/terminal/location_report.h"
#include "../codec/terminal/term_register.h"
#include "../codec/platform/term_register_resp.h"

void jtt808_handler::on_read(std::shared_ptr<channel> ch, const unsigned char* ptr, int size) {
    if (size >= 4 * 1024) {
        return;
    }
    int start = find_mark(ptr, 0, size);
    if (start < 0) {
        LOG(INFO) << "丢弃 " << size;
    }

    int cur = -1;
    do {
        cur = find_mark(ptr, start + 1, size);
        if (cur >= 0) {
            process_frame(ch, ptr, start, cur + 1);
            start = find_mark(ptr, cur + 1, size);

            if (start > cur + 1) {
                LOG(INFO) << "丢弃 " << start - cur - 1;
            }
        } else {
            LOG(INFO) << "丢弃：" << (size - start + 1);
            break;
        }
    } while (start >= 0);
}

void jtt808_handler::on_close(std::shared_ptr<channel> ch, boost::system::error_code ec) {
    LOG(INFO) << "关闭";
}

void jtt808_handler::on_error(std::shared_ptr<channel> ch, boost::system::error_code ec) {
    // LOG(INFO) << "出错" << ec.message();
    ch->close();
}

void jtt808_handler::process_frame(std::shared_ptr<channel> ch, const unsigned char* ptr, int start, int end) {
    int count = ++counter_;
    if (count % 2000 == 0) {
        LOG(INFO) << "接收：" << count;
    }
    if (end - start < 14) {
        return;
    }
    data_pack dp = decode_data_pack(ptr, start, end);
    // LOG(INFO) << dp.get_sim() << ":" << dp.get_seq_no();
    if (dp.get_msg_id() == 0x0200) {
        std::shared_ptr<location_report> lr = std::dynamic_pointer_cast<location_report>(dp.get_body());
        // LOG(INFO) << dp.get_seq_no() << "|" << dp.get_sim() << ": " << lr->get_lng() << ", " << lr->get_lat();
        location loc(dp);
//        if (!saver_.save(loc)) {
//            LOG(WARNING) << "丢弃1条";
//        }

        data_pack re;
        re.set_msg_id(0x8001);
        re.set_sim(dp.get_sim());
        auto body = std::make_shared<plat_common_resp>();
        body->set_term_msg_id(dp.get_msg_id());
        body->set_term_seq_no(dp.get_seq_no());
        body->set_result(0);
        re.set_body(body);
        ch->write(std::move(re.encode()));
    } else if (dp.get_msg_id() == 0x0100) {
        std::shared_ptr<term_register> tr = std::dynamic_pointer_cast<term_register>(dp.get_body());
        // LOG(INFO) << dp.get_seq_no() << "|" << dp.get_sim() << ": " << tr->get_license();
        data_pack re;
        re.set_msg_id(0x8100);
        re.set_sim(dp.get_sim());
        auto resp = std::make_shared<term_register_resp>();
        resp->set_term_seq_no(dp.get_seq_no());
        resp->set_result(0);
        resp->set_auth("abcdef");
        re.set_body(resp);
        ch->write(std::move(re.encode()));
    } else {
        LOG(INFO) << "ERROR: " << dp.get_msg_id();
    }
}

int jtt808_handler::find_mark(const unsigned char* ptr, int start, int stop) {
    for (int i = start; i < stop; i++) {
        if (ptr[i] == 0x7E) {
            return i;
        }
    }
    return -1;
}